//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <winhack.h>
#include "dispatcher.h"
#include "sdl.h"
#include "notifiercenter.h"
#include "simulator.h"
//////////////////////////////////////////////////
typedef struct DECL_PACKED _touch_data {
    short dir;
    short x;
    short y ;
}TOUCH_DATA;

/////////////////////////////////////////////////

CEventDispatcher::CEventDispatcher()
{
    memset(&m_event, 0, sizeof(SDL_Event));
    m_pShadowMgr = GetShadowManager();

    m_pFocusShadow = NULL;
}

void CEventDispatcher::Loop()
{
    Boolean   bQuitFlag = FALSE;

    while (!bQuitFlag) {
        int res = SDL_WaitEvent(&m_event);
        if (res <= 0) {
            continue;
        }

        if (m_event.type == SDL_QUIT) {
            bQuitFlag = TRUE;
            continue;
        }

        Dispatch();
    }
}

void CEventDispatcher::RequestToQuit()
{
    SDL_Event event;

    event.type = SDL_QUIT;
    SDL_PushEvent(&event);
}

static short MapToButtonDir(Uint8 type)
{
    switch(type) {
    case SDL_MOUSEMOTION:
        return 2;
    case SDL_MOUSEBUTTONDOWN:
        return 1;
    case SDL_MOUSEBUTTONUP:
        return 0;
    default:
        assert(0);
    }
    assert(0);
    return 0;
}

extern int MoveTheWindow(int, int);
extern bool  g_isSimulator;
EXTERN BYTE* g_sharedMemoryAddress;

void CEventDispatcher::Dispatch()
{
    CShadow     * pFocus  = NULL;

    switch(m_event.type) {
    case SDL_MOUSEMOTION:
    case SDL_MOUSEBUTTONDOWN:
    case SDL_MOUSEBUTTONUP:
        {
            // Hack Code to move the widget window.
            static Int32 posX = -1, posY = -1;
            if ((SDL_MOUSEBUTTONDOWN == m_event.type)
                 && (SDL_BUTTON_RIGHT== m_event.button.button)
                 && (SDL_PRESSED == m_event.button.state)) {
                 posX = m_event.button.x;
                 posY = m_event.button.y;
            }
            if ((SDL_MOUSEBUTTONUP == m_event.type)
                 && (SDL_BUTTON_RIGHT == m_event.button.button)
                 && (SDL_RELEASED == m_event.button.state)) {
                 posX = -1;
                 posY = -1;
            }




            if ((SDL_MOUSEMOTION == m_event.type)
                 && (posX >= 0)
                 && (posY >= 0)) {
                 MoveTheWindow(posX, posY);
                 return;
            }
        }
        
        {
            static BOOL s_bMousePressState = FALSE;
            if ((SDL_MOUSEBUTTONDOWN == m_event.type)
                 && (SDL_BUTTON_LEFT== m_event.button.button)
                 && (SDL_PRESSED == m_event.button.state)) {
                 s_bMousePressState=TRUE;
             }
             if ((SDL_MOUSEBUTTONUP == m_event.type)
                 && (SDL_BUTTON_LEFT== m_event.button.button)
                 && (SDL_RELEASED == m_event.button.state)) {
                 s_bMousePressState=FALSE;
             }

              if ((SDL_MOUSEMOTION == m_event.type) && (!s_bMousePressState))
                  return ;
              
             
        }
        
        pFocus = m_pShadowMgr->GetFocus(m_event.button.x, m_event.button.y);
        if (NULL == pFocus) {
            return;
        }

        TOUCH_DATA touchData;
        touchData.dir = MapToButtonDir(m_event.type);
        touchData.x = pFocus->Transform2RelativeX(m_event.button.x);
        touchData.y = pFocus->Transform2RelativeY(m_event.button.y);

        if (NULL != pFocus->GetMouse()) {
            MouseParams mouseParams;
            mouseParams.pMouse = pFocus->GetMouse();
            mouseParams.pTouchData = (PVoid)&touchData;
            mouseParams.pSDLEvent = (PVoid)&m_event;

            CallNotifier(SERVICE_MOUSE, 0, (void *)&mouseParams);
        }
        
        break;
    
    case SDL_KEYDOWN:
    case SDL_KEYUP:
         pFocus = m_pShadowMgr->GetFocus();
         assert(NULL != pFocus);

         if (NULL != pFocus->GetKeyboard()) {
             KeyboardParams keyboardParams;
             keyboardParams.pKeyboard = pFocus->GetKeyboard();
             keyboardParams.pParams = (PVoid)&m_event;

             CallNotifier(SERVICE_KEYPAD, 0, (void *)&keyboardParams);
         }
         break;
         
    default:
         break;
    }
}

